#include "Grid.h"

namespace Helper
{
	Grid::Grid(Ogre::SceneManager *sceneMgr)
	{
		m_pSceneMgr = sceneMgr;

		m_pRaySceneQuery = m_pSceneMgr->createRayQuery(Ogre::Ray());

		m_pGrid = m_pSceneMgr->createManualObject("Grid");
	}

	Grid::~Grid(void)
	{
		delete m_pGrid;

		m_pSceneMgr->destroyQuery(m_pRaySceneQuery);

		delete m_pSceneMgr;
	}

	void Grid::CreateGrid(float spacing, float terrainWidth, float terrainDepth, float terrainSize)
	{
		float height = 0.01f;

		m_pGrid->begin("BaseBlackNoLighting", Ogre::RenderOperation::OT_LINE_LIST);

		float numRows = terrainWidth / spacing;
		float numColumns = terrainDepth / spacing;
		float spacingWidth = terrainWidth / (terrainSize - 1);
		float spacingDepth = terrainDepth / (terrainSize -1);

		for(int i = 0; i < numRows; i++)
		{
			int startHeight = 0;

			for(int u = 0; u < terrainSize; u++)
			{
				Ogre::Vector3 startLine;
				Ogre::Vector3 endLine;

				startLine.x = (i * spacing) - (terrainWidth / 2);
				endLine.x = (i * spacing) - (terrainWidth / 2);

				if(i == 0)
					startLine.y = getTerrainHeight(startLine.x, startLine.z) + height;
				else
					startLine.y = startHeight;
				endLine.y = getTerrainHeight(endLine.x, endLine.z) + height;
				
				startLine.z = (u * spacingDepth) - (terrainDepth / 2);
				endLine.z = ((u + 1) * spacingDepth) - (terrainDepth / 2);

				startHeight = endLine.y;

				m_pGrid->position(startLine);
				m_pGrid->position(endLine);
			}
		}

		for(int i = 0; i < numColumns; i++)
		{
			int startHeight = 0;

			for(int u = 0; u < terrainSize; u++)
			{
				Ogre::Vector3 startLine;
				Ogre::Vector3 endLine;

				startLine.z = (i * spacing) - (terrainDepth / 2);
				endLine.z = (i * spacing) - (terrainDepth / 2);

				if(i == 0)
					startLine.y = getTerrainHeight(startLine.x, startLine.z) + height;
				else
					startLine.y = startHeight;
				endLine.y = getTerrainHeight(endLine.x, endLine.z) + height;
				
				startLine.x = (u * spacingWidth) - (terrainWidth / 2);
				endLine.x = ((u + 1) * spacingWidth) - (terrainWidth / 2);

				startHeight = endLine.y;

				m_pGrid->position(startLine);
				m_pGrid->position(endLine);
			}
		}

		m_pGrid->end();
	}

	float Grid::getTerrainHeight(float x, float y)
	{
		Ogre::Ray terrainRay(Ogre::Vector3(x, 5000, y), Ogre::Vector3::NEGATIVE_UNIT_Y);
		m_pRaySceneQuery->setRay(terrainRay);

		Ogre::RaySceneQueryResult result = m_pRaySceneQuery->execute();
		Ogre::RaySceneQueryResult::iterator itr = result.begin();

		if(itr != result.end() && itr->worldFragment)
			return itr->worldFragment->singleIntersection.y;

		return 0;
	}

	void Grid::setVisible(bool visible)
	{
		m_pGrid->setVisible(visible);
	}
}